﻿//tetris._FallingObject is abstract class that is inherited by all Tetris game falling objects. It creates all the functionality for moving and rotating.
//It also defines base properties (center, rotation and body) for all inheritors. 
//body property is an array of tetris.Block objects.
//center property is a tetris.Vector2D object describing the center point of the object.
//rotation property has 4 possible values (0, 90, 180 and 270) describing the current rotation of the falling object.
//do not change any of the properties directly, because this will cause false calculations!
//use only public methods for moving objects
(function () {
    var FallingObject = function () {
        this._relativeBody = [];

        this.getBody = [];
        this.center = new tetris.Vector2D(0, 0);
        this.rotation = 0;
    };
    FallingObject.prototype._recalculateBody = function () {
        switch (this.rotation) {
            case 0:
                for (var i = 0; i < this._relativeBody.length; i++) {
                    this.getBody[i].coordinate.x = this.center.x + this._relativeBody[i].coordinate.x;
                    this.getBody[i].coordinate.y = this.center.y + this._relativeBody[i].coordinate.y;
                    this.getBody[i].color = this._relativeBody[i].color;
                }
                break;
            case 90:
                for (var i = 0; i < this._relativeBody.length; i++) {
                    this.getBody[i].coordinate.x = this.center.x + this._relativeBody[i].coordinate.y;
                    this.getBody[i].coordinate.y = this.center.y - this._relativeBody[i].coordinate.x;
                    this.getBody[i].color = this._relativeBody[i].color;
                }
                break;
            case 180:
                for (var i = 0; i < this._relativeBody.length; i++) {
                    this.getBody[i].coordinate.x = this.center.x - this._relativeBody[i].coordinate.x;
                    this.getBody[i].coordinate.y = this.center.y - this._relativeBody[i].coordinate.y;
                    this.getBody[i].color = this._relativeBody[i].color;
                }
                break;
            case 270:
                for (var i = 0; i < this._relativeBody.length; i++) {
                    this.getBody[i].coordinate.x = this.center.x - this._relativeBody[i].coordinate.y;
                    this.getBody[i].coordinate.y = this.center.y + this._relativeBody[i].coordinate.x;
                    this.getBody[i].color = this._relativeBody[i].color;
                }
                break;
            default:
                throw new Error("Invalid rotation " + this.rotation);
                break;
        }
    };
    FallingObject.prototype.moveLeft = function () {
        this.center.x--;
        this._recalculateBody();
    };
    FallingObject.prototype.moveRight = function () {
        this.center.x++;
        this._recalculateBody();
    };
    FallingObject.prototype.moveUp = function () {
        this.center.y--;
        this._recalculateBody();
    };
    FallingObject.prototype.moveDown = function () {
        this.center.y++;
        this._recalculateBody();
    };
    FallingObject.prototype.moveTo = function (x, y) {
        this.center.x = x;
        this.center.y = y;
        this._recalculateBody();
    };
    FallingObject.prototype.rotate = function () {
        this.rotation += 90;
        if (this.rotation > 270) {
            this.rotation = 0;
        }
        this._recalculateBody();
    };
    FallingObject.prototype.rotateBack = function () {
        this.rotation -= 90;
        if (this.rotation < 0) {
            this.rotation = 270;
        }
        this._recalculateBody();
    };
    FallingObject.prototype.rotateTo = function (angle0or90or180or270) {
        this.rotation = angle0or90or180or270;
        this._recalculateBody();
    };
    FallingObject.prototype.toString = function () {
        var result = "Center: " + this.center.toString();
        result += "\nRotation: " + this.rotation;
        result += "\nRelativeBody: ";
        for (var i = 0; i < this._relativeBody.length; i++) {
            result += this._relativeBody[i].coordinate.toString() + " ";
        }
        result += "\nBody: ";
        for (var i = 0; i < this.getBody.length; i++) {
            result += this.getBody[i].coordinate.toString() + " ";
        }
        result += "\n";

        return result;
    };

    tetris._FallingObject = FallingObject;
})();